<?php
/**
 * Created by PhpStorm.
 * User: vbolshov
 * Date: 01.10.2010
 * Time: 10:54:35
 */

namespace km\filter;

class Filter {
	static private $inputFilters = array();
	/**
	 * @static
	 * @return InputFilter
	 */
	static function post()
	{
		return self::getInputFilter(INPUT_POST);
	}
	/**
	 * @static
	 * @return InputFilter
	 */
	static function get()
	{
		return self::getInputFilter(INPUT_GET);
	}
	/**
	 * @static
	 * @return InputFilter
	 */
	static function request()
	{
		return self::getInputFilter(INPUT_REQUEST);
	}
	/**
	 * @static
	 * @param  $val
	 * @param  $min
	 * @param  $max
	 * @param  $flags
	 * @return Value
	 */
	static function int($val, $min = null, $max = null, $flags = null)
	{
		$optionsAndFlags = array();
		if ((null !== $min) || (null !== $max)) {
			$options = array();
			if (null !== $min) {
				$options['min_range'] = $min;
			}
			if (null !== $max) {
				$options['max_range'] = $max;
			}
			$optionsAndFlags['options'] = $options;
		}
		if (null !== $flags) {
			$optionsAndFlags['flags'] = $flags;
		}
		return new Value(filter_var($val, FILTER_VALIDATE_INT, $optionsAndFlags));
	}
	/**
	 * @static
	 * @param  $val
	 * @param  $min
	 * @param  $max
	 * @return Value
	 */
	static function intArray($val, $min = null, $max = null)
	{
		return self::int($val, $min, $max, FILTER_REQUIRE_ARRAY);
	}
	/**
	 * @static
	 * @param  $val
	 * @return Value
	 */
	static function positiveInt($val)
	{
		return self::int($val, 1);
	}
	/**
	 * @static
	 * @param  $val
	 * @return Value
	 */
	static function positiveIntArray($val)
	{
		return self::int($val, 1, null, FILTER_REQUIRE_ARRAY);
	}
	/**
	 * @static
	 * @param  $val
	 * @return Value
	 */
	static function raw($val)
	{
		return new Value(filter_var($val, FILTER_UNSAFE_RAW));
	}
	/**
	 * @static
	 * @param mixed $val
	 * @param int $max maximum allowed length
	 * @return Value
	 */
	static function str($val, $max = null, $min = null)
	{
		if ($ret = filter_var($val, FILTER_SANITIZE_STRING)) {
			if ($max && (mb_strlen($ret) > $max)) {
				$ret = false;
			} elseif ($min && (mb_strlen($ret) < $min)) {
				$ret = false;
			}
		}
		return new Value($ret);
	}
	/**
	 * @static
	 * @param mixed $val
	 * @param callback $cb
	 * @return Value
	 */
	static function callback($val, $cb)
	{
		return new Value(filter_var($val, FILTER_CALLBACK, array('options' => $cb)));
	}
	/**
	 * @static
	 * @param  $type
	 * @return InputFilter
	 */
	static private function getInputFilter($type)
	{
		if (isset(self::$inputFilters[$type])) {
			return self::$inputFilters[$type];
		} else {
			return self::$inputFilters[$type] = new InputFilter($type);
		}
	}
}

class Value {
	private $value;
	private $default = null;
	function __construct($value)
	{
		$this->value = $value;
	}
	/**
	 * @param  $value
	 * @return Value
	 */
	function setDefault($value)
	{
		$this->default = $value;
		return $this;
	}
	/**
	 * @return mixed
	 */
	function getBoolean()
	{
		return (bool) $this->value;
	}
	/**
	 * @return mixed
	 */
	function export()
	{
		if (is_string($this->value)) {
			return $this->value ?: $this->default;
		} elseif (is_null($this->value)) {
			return $this->default;
		} else {
			return (false === $this->value) ? $this->default : $this->value;
		}
	}
}